// This File is part of the "nyaqt" Project
// 
// Copyright  2009 sometmes@gmail.com
// All rights reserved
// 
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.TextEditor.Document;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using nyaqt.Plugins;
using System.Collections.Specialized;

namespace nyaqt
{
    public partial class QueryWindowForm : Form
    {
        Dictionary<TabPage, EditingTabController> _editingTabList = new Dictionary<TabPage, EditingTabController>();
        TabPage _contextTabPage = null;
        DatabaseTreeController _treeController = null;
        Dictionary<string, ContextMenuStrip> _tabMenus = null;
        private System.Windows.Forms.Timer _timerElapsed;

        public QueryWindowForm()
        {
            InitializeComponent();
            filesTabControl.Selected += new TabControlEventHandler(filesTabControl_Selected);
            filesTabControl.Deselected += new TabControlEventHandler(filesTabControl_Deselected);
            rowCountStatusLabel.Text = "";
            toolStripStatusLabel2.Text = "";
            databaseBrowserTreeView.Nodes.Clear();
            _treeController = new DatabaseTreeController(databaseBrowserTreeView);
            _timerElapsed = new System.Windows.Forms.Timer(this.components);
            _timerElapsed.Enabled = false;
            _timerElapsed.Tick += new EventHandler(_timerElapsed_Tick);
        }

        void _timerElapsed_Tick(object sender, EventArgs e)
        {
            EditingTabController c = _editingTabList[filesTabControl.SelectedTab];
            durationStatusLabel.Text = string.Format("{0:00}:{1:00}:{2:00}", c.ExecDuration.Hours, c.ExecDuration.Minutes, c.ExecDuration.Seconds);
        }

        void filesTabControl_Deselected(object sender, TabControlEventArgs e)
        {
            _contextTabPage = null;
            if (e.TabPage == null) return;
            EditingTabController cont = _editingTabList[e.TabPage];
            if (cont == null) return;
            WinForms.DisableRestore(cont.EnabledState);
            UnBindActiveTabEvents(cont);
        }

        void filesTabControl_Selected(object sender, TabControlEventArgs e)
        {
            if (e.TabPage == null) return;
            _contextTabPage = e.TabPage;
            EditingTabController cont = _editingTabList[e.TabPage];
            if (cont == null) return;
            WinForms.DisableAgain(cont.EnabledState);
            BindActiveTabEvents(cont);
            UpdateConnectionStatusUI();
        }

        private void QueryWindowForm_Load(object sender, EventArgs e)
        {
            Dictionary<string, ContextMenuStrip> treeMenus = new Dictionary<string, ContextMenuStrip>();
            treeMenus.Add("TABLE", tableContextMenu);
            treeMenus.Add("RELATION", relationContextMenu);
            _treeController.TreeMenus = treeMenus;
            _tabMenus = new Dictionary<string, ContextMenuStrip>();
            _tabMenus.Add("EDITGRID", editGridContextMenu);
            //filesTabControl.Dock = DockStyle.Fill;
            filesTabControl.Left = -2;
            filesTabControl.Top = 0;
            filesTabControl.Width = splitContainer3.Panel1.Width - (filesTabControl.Left * 2);
            filesTabControl.Height = splitContainer3.Panel1.Height +9;
            filesTabControl.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top | AnchorStyles.Bottom;
            filesTabControl.ShowToolTips = true;
            splitContainer2.Dock = DockStyle.Fill;
            databaseBrowserTreeView.Dock = DockStyle.Fill;
            propertyGrid1.Dock = DockStyle.Fill;
            splitContainer3.Panel2Collapsed = true;

            FileNewCommand(Program.TestCommand);
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            BindActiveTabEvents(cont);
            UpdateFileCommands();
        }

        void BindActiveTabEvents(EditingTabController cont)
        {
            if (cont == null) return;
            cont.StatusChange += new EditingTabController.StatusChangeDelegate(QueryWindowForm_StatusChange);
            cont.ExecController.Start += new StatementExecutionController.StartDelegate(_execController_Start);
            cont.ExecController.End += new StatementExecutionController.EndDelegate(_execController_End);
            cont.UpdateFindText += new EditingTabController.UpdateFindTextDelegate(cont_UpdateFindText);
        }

        FindOptions cont_UpdateFindText(string textToFind)
        {
            findToolStripTextBox.Text = textToFind;
            return new FindOptions(matchCaseToolStripMenuItem.Checked, matchWholeWordToolStripMenuItem.Checked);
        }

        void UnBindActiveTabEvents(EditingTabController cont)
        {
            if (cont == null) return;
            cont.StatusChange -= new EditingTabController.StatusChangeDelegate(QueryWindowForm_StatusChange);
            cont.ExecController.Start -= new StatementExecutionController.StartDelegate(_execController_Start);
            cont.ExecController.End -= new StatementExecutionController.EndDelegate(_execController_End);
        }

        void QueryWindowForm_StatusChange(int rowcount, bool loading)
        {
            if (rowcount != -1)
            {
                if (loading)
                    rowCountStatusLabel.Text = "Rows: ... " + rowcount.ToString();
                else
                    rowCountStatusLabel.Text = "Rows: " + rowcount.ToString();
            }
            else
                rowCountStatusLabel.Text = "";
            UpdateConnectionStatusUI();
        }


        void _execController_Start()
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            WinForms.Disable(connectToolStripButton, cont.EnabledState);
            WinForms.Disable(executeToolStripButton, cont.EnabledState);
            WinForms.Disable(executeQueryToolStripMenuItem, cont.EnabledState);
            WinForms.Enable(cancelToolStripButton, cont.EnabledState);
            WinForms.Enable(cancelToolStripMenuItem, cont.EnabledState);
            toolStripStatusLabel2.Text = "Executing";
            _timerElapsed.Enabled = true;
        }

        void _execController_End()
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            WinForms.DisableRestore(cont.EnabledState);
            cont.EnabledState.Clear();
            toolStripStatusLabel2.Text = "Finished";
            _timerElapsed.Enabled = false;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void newWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
        }

        void Connect(EditingTabController cont)
        {
            IDbConnection cn2;
            Connect(cont, false, out cn2);
        }

        DialogResult Connect(EditingTabController cont, bool connectTwoTimes, out IDbConnection cn2)
        {
            NewConnectionForm f = new NewConnectionForm();
            f.ConnectTwoTimes = connectTwoTimes;
            if (cont.ConnectionInfo is EmptyConnectionInfo)
            {
                if (My.Settings.LastConnection != null)
                    f.Connection = My.Settings.LastConnection.Copy();
                else
                    f.Connection = cont.ConnectionInfo.Copy(); //EmptyConnectionInfo
            }
            else
            {
                if (cont.TestCommand == null)
                {
                    f.Connection = cont.ConnectionInfo.Copy();
                }
                else
                {
                    f.Connection = cont.ConnectionInfo;
                }
            }
            cn2 = null;
            DialogResult res = f.ShowDialog();
            if (DialogResult.OK == res)
            {
                if (_editingTabList.Count == 0)
                    FileNewCommand(null);
                cont.ExecController.ConnectionInfo = f.Connection;
                cont.ConnectionInfo = f.Connection;
                cont.UpdateTabTitle(false);
                if (connectTwoTimes)
                    cn2 = f.SecondConnection;
            }
            UpdateConnectionCommands();
            UpdateConnectionStatusUI();
            return res;
        }

        private void ConnectCommand(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            Connect(cont);
        }

        private void splitContainer3_DoubleClick(object sender, EventArgs e)
        {
            splitContainer3.Panel2Collapsed = true;
        }

        private void testToolStripMenuItem_Click(object sender, EventArgs e)
        {
            filesTabControl.SelectedTab.ContextMenuStrip.Show();
        }

        private void FileNewCommand(object sender, EventArgs e)
        {
            FileNewCommand(null);
        }

        private EditingTabController FileNewCommand(TestCommand testcmd)
        {
            EditingTabController c = new EditingTabController();
            c.TabMenus = _tabMenus;
            c.FileName = null;
            TabPage tab = c.Tab;
            tab.Text = SR.NewFile + (filesTabControl.TabPages.Count + 1);
            filesTabControl.TabPages.Add(tab);
            _editingTabList.Add(c.Tab, c);
            filesTabControl.SelectedTab = tab;
            c.TestCommand = testcmd;
            if (testcmd != null)
                c.ConnectionInfo = BuildConnectionInfoFromTestCommand(testcmd);
            c.Reload();
            UpdateFileCommands();
            return c;
        }

        ConnectionInfo BuildConnectionInfoFromTestCommand(TestCommand testcmd)
        {
            ConnectionInfo info = new ConnectionInfo();
            info.ProviderInvariantName = testcmd.ProviderInvariantName;
            if (testcmd.SupportsDbProviderFactory)
                info.Version = 2;
            else
                info.Version = 1;

            info.ProviderName = "//" + info.ProviderInvariantName + "//";
            IDbConnection cn = testcmd.Command.Connection;
            if (cn != null)
            {
                info.ConnectionString = cn.ConnectionString;
                info.Current = cn;
            }
            return info;
        }

        private void FileOpenCommand(string filename)
        {
            EditingTabController c;
            bool toadd = true;
            if (filesTabControl.TabCount > 0)
            {
                c = _editingTabList[filesTabControl.SelectedTab];
                if (!(c.IsEmpty && c.FileName == null))
                    c = new EditingTabController();
                else
                    toadd = false;
            }
            else
                c = new EditingTabController();

            c.TabMenus = _tabMenus;
            c.FileName = filename;
            c.UpdateTabTitle(true);
            TabPage tab = c.Tab;
            if (toadd)
            {
                filesTabControl.TabPages.Add(tab);
                _editingTabList.Add(c.Tab, c);
                filesTabControl.SelectedTab = tab;
            }
            c.Reload();
        }

        private void FileOpenCommand(object sender, EventArgs e)
        {
            if (DialogResult.OK == openFileDialog1.ShowDialog())
            {
                foreach (string filename in openFileDialog1.FileNames)
                {
                    FileOpenCommand(filename);
                }
            }
        }

        private void filesTabControl_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                _contextTabPage = TabAtPoint(filesTabControl, e.Location);
                if (this._contextTabPage!=null)
                    fileContextMenu.Show(filesTabControl, e.Location);
            }
        }

        private TabPage TabAtPoint(TabControl tabCtrl, Point location)
        {
            for (int i = 0; i < tabCtrl.TabCount; i++)
            {
                Rectangle r = tabCtrl.GetTabRect(i);
                if (r.Contains(location))
                {
                    return tabCtrl.TabPages[i];
                }
            }
            return null;
        }

        private void CloseTabCommand(object sender, EventArgs e)
        {
            int index = -1;
            if (this._contextTabPage == null || this._contextTabPage == filesTabControl.SelectedTab)
                this._contextTabPage = filesTabControl.SelectedTab;
            if (this._contextTabPage == null) return; // nothing to close;
            TabPage page = this._contextTabPage;
            index = filesTabControl.TabPages.IndexOf(page);
            _editingTabList[page].Close();
            if (index > 0)
                filesTabControl.SelectedIndex = index - 1;
            if (!filesTabControl.TabPages.Contains(page))
                _editingTabList.Remove(page);
            this._contextTabPage = null;
            UpdateFileCommands();
        }

        void UpdateFileCommands()
        {
            if (filesTabControl.TabCount == 0)
            {
                saveToolStripMenuItem1.Enabled = false;
                saveToolStripButton.Enabled = false;
                commentRemoveCommentToolStripMenuItem.Enabled = false;
                insertLineAboveToolStripMenuItem.Enabled = false;
                UpdateConnectionCommands();
                UpdateConnectionStatusUI();
            }
            else
            {
                saveToolStripMenuItem1.Enabled = true;
                saveToolStripButton.Enabled = true;
                commentRemoveCommentToolStripMenuItem.Enabled = true;
                insertLineAboveToolStripMenuItem.Enabled = true;
                UpdateConnectionCommands();
                UpdateConnectionStatusUI();
            }
        }

        void UpdateConnectionStatusUI()
        {
            if (filesTabControl.SelectedTab != null && _editingTabList[filesTabControl.SelectedTab].ConnectionInfo != null && _editingTabList[filesTabControl.SelectedTab].ConnectionInfo.Current != null)
            {
                userStatusLabel.Visible = true;
                databaseStatusLabel.Visible = true;
                serverStatusLabel.Visible = true;
                durationStatusLabel.Visible = true;
                EditingTabController c = _editingTabList[filesTabControl.SelectedTab];
                userStatusLabel.Text = c.ConnectionInfo.ConnectionProperties.UserName;
                databaseStatusLabel.Text = c.ConnectionInfo.ConnectionProperties.Database;
                serverStatusLabel.Text = c.ConnectionInfo.ConnectionProperties.Server;
                _timerElapsed_Tick(null, null);
            }
            else
            {
                userStatusLabel.Visible = false;
                databaseStatusLabel.Visible = false;
                serverStatusLabel.Visible = false;
                durationStatusLabel.Visible = false;
            }
        }

        void UpdateConnectionCommands()
        {
            if (filesTabControl.TabCount == 0)
            {
                connectToolStripButton.Enabled = false;
                executeToolStripButton.Enabled = false;
                executeQueryToolStripMenuItem.Enabled = false;
                executeAssistedToolStripMenuItem.Enabled = false;
                newConnectionToolStripMenuItem.Enabled = false;
                resetConnectionToolStripMenuItem.Enabled = false;
                closeConnectionToolStripMenuItem.Enabled = false;
                viewConnectionPropertiesToolStripMenuItem.Enabled = false;
                insertDeclarationsRegionToolStripMenuItem.Enabled = false;
            }
            else
            {
                EditingTabController c = _editingTabList[filesTabControl.SelectedTab];
                if (c.ConnectionInfo == null || c.ConnectionInfo is EmptyConnectionInfo || c.ConnectionInfo.Current == null || c.ConnectionInfo.Current.State != ConnectionState.Open)
                {
                    connectToolStripButton.Enabled = true;
                    executeToolStripButton.Enabled = true;
                    executeQueryToolStripMenuItem.Enabled = true;
                    executeAssistedToolStripMenuItem.Enabled = true;
                    newConnectionToolStripMenuItem.Enabled = true;
                    resetConnectionToolStripMenuItem.Enabled = false;
                    closeConnectionToolStripMenuItem.Enabled = false;
                    viewConnectionPropertiesToolStripMenuItem.Enabled = false;
                    insertDeclarationsRegionToolStripMenuItem.Enabled = true;
                }
                else
                {
                    connectToolStripButton.Enabled = true;
                    executeToolStripButton.Enabled = true;
                    executeQueryToolStripMenuItem.Enabled = true;
                    executeAssistedToolStripMenuItem.Enabled = true;
                    newConnectionToolStripMenuItem.Enabled = true;
                    resetConnectionToolStripMenuItem.Enabled = true;
                    closeConnectionToolStripMenuItem.Enabled = true;
                    viewConnectionPropertiesToolStripMenuItem.Enabled = true;
                    insertDeclarationsRegionToolStripMenuItem.Enabled = true;
                }
            }
        }

        private void FileSaveCommand(object sender, EventArgs e)
        {
            if (this._contextTabPage == null)
                this._contextTabPage = filesTabControl.SelectedTab;

            _editingTabList[this._contextTabPage].Save();

        }

        private void QueryWindowForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Dictionary<TabPage, EditingTabController> newlist = new Dictionary<TabPage, EditingTabController>(this._editingTabList);
            foreach (KeyValuePair<TabPage,EditingTabController> pair in _editingTabList)
            {
                pair.Value.Close();
                if (filesTabControl.TabPages.Contains(pair.Key))
                    break;
                newlist.Remove(pair.Key);
            }

            this._editingTabList = newlist;
            if (this._editingTabList.Count != 0)
                e.Cancel = true;
        }

        private void executeQueryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];

            if (cont.ExecController.Connection == null || cont.ExecController.Connection.State == ConnectionState.Closed)
                ConnectCommand(null, null);
            if (cont.ExecController.Connection == null || cont.ExecController.Connection.State == ConnectionState.Closed)
                return;
            cont.ExecController.ExecuteAsync(cont.Script, cont.Selection, cont.TestCommand);
        }

        private void cancelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.ExecController.Abort();
            toolStripStatusLabel2.Text = "Canceled";
        }

        private void switchPaneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.SwitchPane();
        }

        object _noevent = new object();

        private void resultsToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            enforceConstraintsToolStripMenuItem.Tag = _noevent;
            enforceConstraintsToolStripMenuItem.Checked = true;
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            enforceConstraintsToolStripMenuItem.Checked = cont.EnforceConstraints;
            enforceConstraintsToolStripMenuItem.Tag = null;
        }

        private void enforceConstraintsToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            if (enforceConstraintsToolStripMenuItem.Tag == _noevent) return;
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            if (cont.EnforceConstraints)
                cont.DisableConstraints();
            else
                cont.EnableConstraints();
        }

        private void connectDatabaseExplorerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _treeController.AddServer(null, null);
            databaseBrowserTreeView.Focus();
        }

        private void selectTop1000RowsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode table = _treeController.ContextNode;
            TreeNode columns = table.FirstNode;
            if (columns.Nodes.Count > 0 && columns.FirstNode is DatabaseTreeController.WaitTreeNode)
            {
                _treeController.LoadNodeAssinc(columns, new RunWorkerCompletedEventHandler(selectTop1000Rows_RunWorkerCompleted));
            }
            else
                selectTop1000Rows_RunWorkerCompleted(columns, null);
        }

        void selectTop1000Rows_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            TreeNode columns = sender as TreeNode;
            DatabaseTreeController.EntityTreeNode table = columns.Parent as DatabaseTreeController.EntityTreeNode;
            List<DatabaseEntityInfo> entities = new List<DatabaseEntityInfo>();
            foreach (DatabaseTreeController.EntityTreeNode column in columns.Nodes)
                entities.Add(column.Entity);
            string smt = table.ConnectionProperties.FormatSelectTopQuery(1000, table.Entity, entities);
            //ConnectionInfo cn = table.ServerNode.Connection.Copy();
            ConnectionInfo newcn = table.ServerNode.Connection.ChangeDatabase(table.Entity.DatabaseName);
            NewQueryTabWithStatement(table.Entity.TableName, smt, newcn);
        }

        private void treeContextMenu_Opened(object sender, EventArgs e)
        {
            ContextMenuStrip menu = sender as ContextMenuStrip;
            TreeView tree = menu.SourceControl as TreeView;
            TreeNode node = tree.GetNodeAt(tree.PointToClient(menu.Bounds.Location));
            _treeController.ContextNode = node;
        }

        private void NewQueryTabWithStatement(string name, string statement, ConnectionInfo cn)
        {
            EditingTabController c = null;
            //Should check if tab disconnected or connected to same server+db than explorer
            //if (filesTabControl.TabCount > 0)
            //{
            //    c = _editingTabList[filesTabControl.SelectedTab];
            //    if (c.Script.Length > 0)
            //        c = null;
            //}
            if (c == null)
            {
                c = new EditingTabController();
                c.TabMenus = _tabMenus;
                c.FileName = null;
                c.ConnectionInfo = cn;
                TabPage tab = c.Tab;
                tab.Text = name + " " + (filesTabControl.TabPages.Count + 1);
                filesTabControl.TabPages.Add(tab);
                _editingTabList.Add(c.Tab, c);
                filesTabControl.SelectedTab = tab;
            }
            c.Statement = statement;
            c.Reload();
            this.ActiveControl = toolStrip1;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            
        }

        private void commentRemoveCommentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.ToggleLineComment();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (databaseBrowserTreeView.Focused)
            {
            }
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void insertDeclarationsRegionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.InsertDeclarationsRegion();
        }

        private void QueryWindowForm_KeyPress(object sender, KeyPressEventArgs e)
        {
            
        }

        private void QueryWindowForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                if (cancelToolStripButton.Enabled == true)
                {
                    cancelToolStripMenuItem_Click(null, null);
                }
            }
            else if (e.KeyCode == Keys.Return && e.Control)
            {
                EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
                cont.InsertLineAbove();
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About frm = new About();
            frm.ShowDialog();
        }

        private void selectTop1000JoinRowsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void navigateToTableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _treeController.NavigateToTable(_treeController.ContextNode);
        }

        private void fileServerDatabaseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.TabTitleStyle = EditingTabController.TabTitleStyleEnum.FileName | EditingTabController.TabTitleStyleEnum.Server | EditingTabController.TabTitleStyleEnum.Database;
            cont.UpdateTabTitle(true);
        }

        private void serverDatabaseUserNameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.TabTitleStyle = EditingTabController.TabTitleStyleEnum.Server | EditingTabController.TabTitleStyleEnum.Database | EditingTabController.TabTitleStyleEnum.DbUser;
            cont.UpdateTabTitle(true);
        }

        private void fileContextMenu_Opening(object sender, CancelEventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            if (cont.TabTitleStyle == (EditingTabController.TabTitleStyleEnum.Server | EditingTabController.TabTitleStyleEnum.Database | EditingTabController.TabTitleStyleEnum.DbUser))
            {
                serverDatabaseUserNameToolStripMenuItem.Checked = true;
                fileServerDatabaseToolStripMenuItem.Checked = false;
            }
            else if (cont.TabTitleStyle == (EditingTabController.TabTitleStyleEnum.FileName | EditingTabController.TabTitleStyleEnum.Server | EditingTabController.TabTitleStyleEnum.Database))
            {
                serverDatabaseUserNameToolStripMenuItem.Checked = false;
                fileServerDatabaseToolStripMenuItem.Checked = true;
            }
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _treeController.RefreshNode();
        }

        private void scriptINSERTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode table = _treeController.ContextNode;
            TreeNode columns = table.FirstNode;
            if (columns.Nodes.Count > 0 && columns.FirstNode is DatabaseTreeController.WaitTreeNode)
            {
                _treeController.LoadNodeAssinc(columns, new RunWorkerCompletedEventHandler(scriptINSERT_RunWorkerCompleted));
            }
            else
                scriptINSERT_RunWorkerCompleted(columns, null);
        }

        void scriptINSERT_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            DatabaseTreeController.EntityTreeNode table;
            List<DatabaseEntityInfo> entities;
            List<DatabaseEntityInfo> tables;

            PrepareScriptTreeTable(sender, out table, out entities, out tables);
            string smt = table.ConnectionProperties.FormatInsertScript(null, tables, entities);
            ConnectionInfo cn = table.ServerNode.Connection.Copy();
            NewQueryTabWithStatement(table.Entity.TableName, smt, cn);
        }

        private void scriptUPDATEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode table = _treeController.ContextNode;
            TreeNode columns = table.FirstNode;
            if (columns.Nodes.Count > 0 && columns.FirstNode is DatabaseTreeController.WaitTreeNode)
            {
                _treeController.LoadNodeAssinc(columns, new RunWorkerCompletedEventHandler(scriptUPDATE_RunWorkerCompleted));
            }
            else
                scriptUPDATE_RunWorkerCompleted(columns, null);
        }

        void scriptUPDATE_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            DatabaseTreeController.EntityTreeNode table;
            List<DatabaseEntityInfo> entities;
            List<DatabaseEntityInfo> tables;

            PrepareScriptTreeTable(sender, out table, out entities, out tables);
            string smt = table.ConnectionProperties.FormatUpdateScript(null, null, null, tables, entities);
            ConnectionInfo cn = table.ServerNode.Connection.Copy();
            NewQueryTabWithStatement(table.Entity.TableName, smt, cn);
        }

        private void scriptDELETEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode table = _treeController.ContextNode;
            TreeNode columns = table.FirstNode;
            if (columns.Nodes.Count > 0 && columns.FirstNode is DatabaseTreeController.WaitTreeNode)
            {
                _treeController.LoadNodeAssinc(columns, new RunWorkerCompletedEventHandler(scriptDELETE_RunWorkerCompleted));
            }
            else
                scriptDELETE_RunWorkerCompleted(columns, null);
        }

        void scriptDELETE_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            DatabaseTreeController.EntityTreeNode table;
            List<DatabaseEntityInfo> entities;
            List<DatabaseEntityInfo> tables;

            PrepareScriptTreeTable(sender, out table, out entities, out tables);
            string smt = table.ConnectionProperties.FormatDeleteScript(null, tables, entities);
            ConnectionInfo cn = table.ServerNode.Connection.Copy();
            NewQueryTabWithStatement(table.Entity.TableName, smt, cn);
        }

        private static void PrepareScriptTreeTable(object sender, out DatabaseTreeController.EntityTreeNode table, out List<DatabaseEntityInfo> entities, out List<DatabaseEntityInfo> tables)
        {
            TreeNode columns = sender as TreeNode;
            table = columns.Parent as DatabaseTreeController.EntityTreeNode;
            entities = new List<DatabaseEntityInfo>();
            foreach (DatabaseTreeController.EntityTreeNode column in columns.Nodes)
                entities.Add(column.Entity);
            tables = new List<DatabaseEntityInfo>();
            tables.Add(table.Entity);
        }

        private void explorerToolStripButton_Click(object sender, EventArgs e)
        {
           IDbConnection cn2;
           EditingTabController c = null;
           if (filesTabControl.TabCount != 0)
               c = _editingTabList[filesTabControl.SelectedTab];
           if (c == null)
           {
               Connect(c, true, out cn2);
               ConnectionInfo ci2 = c.ConnectionInfo.Copy();
               ci2.Current = cn2;
               _treeController.AddServer(ci2, c.ConnectionInfo);
           }
           else
           {
               if (c.ConnectionInfo == null || c.ConnectionInfo is EmptyConnectionInfo)
               {
                   if (Connect(c, true, out cn2) != DialogResult.OK) return;
                   ConnectionInfo ci2 = c.ConnectionInfo.Copy();
                   ci2.Current = cn2;
                   _treeController.AddServer(ci2, c.ConnectionInfo);
               }
               else
               {
                   _treeController.AddServer(c.ConnectionInfo.Copy(), c.ConnectionInfo);
               }
           }
           databaseBrowserTreeView.Focus();
        }

        private void scriptRowsForINSERTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            List<Dictionary<string,object>> rows = cont.GridSelectionCurrentValues;
            StringBuilder stm = new StringBuilder();
            foreach (Dictionary<string, object> row in rows)
            {
                List<DatabaseEntityInfo> tables;
                List<DatabaseEntityInfo> columns;
                cont.BuildEntityInfo(out tables, out columns);
                stm.AppendLine(cont.ConnectionInfo.ConnectionProperties.FormatInsertScript(row, tables, columns));
                stm.AppendLine();
            }
            NewQueryTabWithStatement("INSERT", stm.ToString(), cont.ConnectionInfo.Copy());
        }

        private void scriptRowsForUPDATEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            List<Dictionary<string, object>> originals = cont.GridSelectionOriginalValues;
            List<Dictionary<string, object>> currents = cont.GridSelectionCurrentValues;
            StringBuilder stm = new StringBuilder();
            for (int i = 0; i < originals.Count; i++)
            {
                List<DatabaseEntityInfo> tables;
                List<DatabaseEntityInfo> columns;
                cont.BuildEntityInfo(out tables, out columns);
                stm.AppendLine(cont.ConnectionInfo.ConnectionProperties.FormatUpdateScript(originals[i], currents[i], null, tables, columns));
                stm.AppendLine();
            }
            NewQueryTabWithStatement("UPDATE", stm.ToString(), cont.ConnectionInfo.Copy());
        }

        private void scriptCellsForUPDATEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            List<Dictionary<string, object>> originals = cont.GridSelectionOriginalValues;
            List<Dictionary<string, object>> currents = cont.GridSelectionCurrentValues;
            List<List<string>> cells = cont.GridSelectedCells;
            StringBuilder stm = new StringBuilder();
            for (int i =0;i< originals.Count ;i++)
            {
                List<DatabaseEntityInfo> tables;
                List<DatabaseEntityInfo> columns;
                cont.BuildEntityInfo(out tables, out columns);
                stm.AppendLine(cont.ConnectionInfo.ConnectionProperties.FormatUpdateScript(originals[i], currents[i], cells[i], tables, columns));
                stm.AppendLine();
            }
            NewQueryTabWithStatement("UPDATE", stm.ToString(), cont.ConnectionInfo.Copy());
        }

        private void scriptRowsForDELETEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            List<Dictionary<string, object>> originals = cont.GridSelectionOriginalValues;
            StringBuilder stm = new StringBuilder();
            for (int i = 0; i < originals.Count; i++)
            {
                List<DatabaseEntityInfo> tables;
                List<DatabaseEntityInfo> columns;
                cont.BuildEntityInfo(out tables, out columns);
                stm.AppendLine(cont.ConnectionInfo.ConnectionProperties.FormatDeleteScript(originals[i], tables, columns));
                stm.AppendLine();
            }
            NewQueryTabWithStatement("DELETE", stm.ToString(), cont.ConnectionInfo.Copy());
        }






        //BackgroundWorker _bg;
        private void QueryWindowForm_Shown(object sender, EventArgs e)
        {
            this.ActiveControl = toolStrip1;
            //_bg = new BackgroundWorker();
            //_bg.DoWork += new DoWorkEventHandler(work._bg_DoWork);
            //_bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(work._bg_RunWorkerCompleted);
            //_bg.RunWorkerAsync();

            //Form1Work work = new Form1Work();
            //work.Run();
            //Form1 f = new Form1();
            //f._bg = new BackgroundWorker();
            //f.Show();
        }

        private void copyColumnsNameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            List<List<string>> cells = cont.GridSelectedCells;
            if (cells.Count > 0)
            {
                List<string> cols = cells[0];
                string scols = string.Join(", ",cols.ToArray());
                Clipboard.SetText(scols);
            }
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (this.ActiveControl == toolStrip1)
            {
                ToolStripItem target = executeToolStripButton;
                Cursor.Position = toolStrip1.PointToScreen(new Point(target.Bounds.Left + (int)(target.Width * (1 - (1.0 / 5))), target.Bounds.Top + (target.Height / 2)));
                //ToolStripItem current = null;
                //foreach (ToolStripItem item in toolStrip1.Items)
                //    if (item.Selected)
                //    {
                //        current = item;
                //        break;
                //    }

                //ArrowDirection dir = ArrowDirection.Right;
                //if (e.Delta > 0)
                //    dir = ArrowDirection.Left;

                //ToolStripItem next = null;
                //if (current != null)
                //{
                //    next = toolStrip1.GetNextItem(current, dir);
                //    next.Select();
                //}

                //if (next != null)
                //    Cursor.Position = toolStrip1.PointToScreen(new Point(next.Bounds.Left + (next.Width / 5), next.Bounds.Top + next.Height / 2));
            }
        }

        private void toggleBookmarkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.ToggleBookmark();
        }

        private void goToNextBookmarkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.GotoNextBookmark();
        }

        private void goToPreviousBookmarkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.GotoPreviousBookmark();
        }

        private void namedBookmarksToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            if (namedBookmarksToolStripMenuItem.DropDownItems.Contains(emptyToolStripMenuItem))
            {
                AddNamedBookmarks();
            }
        }

        private void AddNamedBookmarks()
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            List<KeyValuePair<string, ICSharpCode.TextEditor.Document.Bookmark>> marks;
            marks = cont.ParseNamedBookmarks();
            namedBookmarksToolStripMenuItem.DropDownItems.Remove(emptyToolStripMenuItem);
            if (marks == null) return;
            foreach (KeyValuePair<string, ICSharpCode.TextEditor.Document.Bookmark> pair in marks)
            {
                ToolStripMenuItem item = new ToolStripMenuItem(pair.Key);
                item.Tag = pair.Value;
                item.Click += new EventHandler(namedBookmark_Click);
                namedBookmarksToolStripMenuItem.DropDownItems.Add(item);
            }
        }

        void namedBookmark_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            ICSharpCode.TextEditor.Document.Bookmark mark = (ICSharpCode.TextEditor.Document.Bookmark)item.Tag;

            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.GotoBookmark(mark);
        }

        private void refreshBookmarksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ToolStripItem olditem1 in namedBookmarksToolStripMenuItem.DropDownItems)
            {
                if (!(olditem1 is ToolStripMenuItem)) continue;
                ToolStripMenuItem olditem = olditem1 as ToolStripMenuItem;
                ICSharpCode.TextEditor.Document.Bookmark mark = (ICSharpCode.TextEditor.Document.Bookmark)olditem.Tag;
                if (mark != null)
                    mark.Document.BookmarkManager.RemoveMark(mark);
            }
            ClearNamedBookmarks();
            AddNamedBookmarks();
            namedBookmarksToolStripMenuItem.ShowDropDown();
        }

        private void ClearNamedBookmarks()
        {
            namedBookmarksToolStripMenuItem.DropDownItems.Clear();
            namedBookmarksToolStripMenuItem.DropDownItems.Add(refreshBookmarksToolStripMenuItem);
            namedBookmarksToolStripMenuItem.DropDownItems.Add(clearToolStripMenuItem);
            namedBookmarksToolStripMenuItem.DropDownItems.Add(bookmarksToolStripSeparator);
        }

        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ClearNamedBookmarks();
        }

        private void findNextToolStripButton_ButtonClick(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.FindNext(findToolStripTextBox.Text, new FindOptions(matchCaseToolStripMenuItem.Checked, matchWholeWordToolStripMenuItem.Checked));
        }

        private void findPrevToolStripButton_Click(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.FindPrevious(findToolStripTextBox.Text, new FindOptions(matchCaseToolStripMenuItem.Checked, matchWholeWordToolStripMenuItem.Checked));
        }

        private void findToolStripMenuItem_Click(object sender, EventArgs e)
        {
            findToolStripTextBox.Focus();
        }

        private void findNextToolStripMenuItem_Click(object sender, EventArgs e)
        {
            findNextToolStripButton_ButtonClick(null, null);
        }

        private void findPreviousToolStripMenuItem_Click(object sender, EventArgs e)
        {
            findPrevToolStripButton_Click(null, null);
        }

        private void testToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            EditingTabController cont = _editingTabList[filesTabControl.SelectedTab];
            cont.ExecController.Test();
        }
    }
}
